package com.miao.websecurity.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.miao.common.entity.R;
import com.miao.common.utils.JWTUtil;
import com.miao.websecurity.entity.*;
import com.miao.websecurity.entity.vo.*;
import com.miao.websecurity.service.*;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * @author MiaoWenqing
 * @description: 角色controller
 * @date 2021/2/1 15:34
 */

@RestController
@RequestMapping("/admin/role")
public class RoleController {


    @Resource
    private SysRoleService sysRoleService;

    @Resource
    private RoleMenuService roleMenuService;

    @Resource
    private SysMenuService sysMenuService;
    @Resource
    private SysApiService sysApiService;

    @Resource
    private AdminService adminService;


    @Resource
    private RoleApiService roleApiService;

    /**
     * 角色添加
     *
     * @param roleAddVO 角色VO
     * @param token  token header
     * @return R
     */
    @PostMapping("/add")
    public R roleAdd(@RequestBody RoleAddVO roleAddVO, @RequestHeader(value = "access-token") String token) {


        long id = IdWorker.getId();
        SysRole sysRole = new SysRole();
        sysRole.setRoleId(String.valueOf(id));
        sysRole.setRoleDes(roleAddVO.getRoleDes());

        if (roleAddVO.getRoleName().substring(0,5).equals("ROLE_")){
            sysRole.setRoleName(roleAddVO.getRoleName());
        }else {

            sysRole.setRoleName("ROLE_"+roleAddVO.getRoleName());
        }


        String s = JWTUtil.analysisToken(token);
        Map map = JSON.parseObject(s, Map.class);
        Admin admin = this.adminService.getById(map.get("adminId").toString()); //1平台 0店铺
        if (admin.getAdminType() == 1 && null == admin.getStoreId()) {
            //平台管理员
            //1.将角色加入 角色表 角色类型为平台管理员
            sysRole.setRoleType(true);
        } else {
            //店铺管理员
            sysRole.setRoleType(false);
        }
        if (!this.sysRoleService.save(sysRole)) {
            return R.error();
        }
        //2.将资源id加入角色资源中间表
        ArrayList<RoleApi> roleApis = new ArrayList<>();
        roleAddVO.getApis().forEach(item -> {
            roleApis.add(new RoleApi(sysRole.getRoleId(), item));
        });
        if (!this.roleApiService.saveBatch(roleApis)) {
            return R.error();
        }


        //3.将菜单id 加入菜单角色中间表
        ArrayList<RoleMenu> roleMenus = new ArrayList<>();


        List<SysMenu> list = this.sysMenuService.list();

        //获取全部菜单
        ArrayList<MenuVO> sysMenus = new ArrayList<>();
        if (admin.getAdminType() == 1 && null == admin.getStoreId()) {
            //平台管理员
            list.forEach(item -> {
                //平台管理员 一级菜单
                if ((null == item.getMenuType() || item.getMenuType()) && null == item.getMenuPar()) {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setChildren(new ArrayList<SysMenu>());
                    menuVO.setMenuDes(item.getMenuDes());
                    menuVO.setMenuIcon(item.getMenuIcon());
                    menuVO.setMenuId(item.getMenuId());
                    menuVO.setMenuType(item.getMenuType());
                    menuVO.setMenuName(item.getMenuName());
                    menuVO.setMenuRouter(item.getMenuRouter());

                    list.forEach(item1 -> {
                        if ((null == item1.getMenuType() || item1.getMenuType()) && menuVO.getMenuId().equals(item1.getMenuPar())) {
                            menuVO.getChildren().add(item1);
                        }

                    });
                    sysMenus.add(menuVO);
                }


            });

        } else {
            //店铺管理员
            list.forEach(item -> {
                //平台管理员 一级菜单
                if ((null == item.getMenuType() || !item.getMenuType()) && null == item.getMenuPar()) {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setChildren(new ArrayList<SysMenu>());
                    menuVO.setMenuDes(item.getMenuDes());
                    menuVO.setMenuIcon(item.getMenuIcon());
                    menuVO.setMenuId(item.getMenuId());
                    menuVO.setMenuType(item.getMenuType());
                    menuVO.setMenuName(item.getMenuName());
                    menuVO.setMenuRouter(item.getMenuRouter());
                    list.forEach(item1 -> {
                        if ((null == item1.getMenuType() || !item1.getMenuType()) && menuVO.getMenuId().equals(item1.getMenuPar())) {
                            menuVO.getChildren().add(item1);
                        }

                    });
                    sysMenus.add(menuVO);
                }


            });
        }



        roleAddVO.getMenus().forEach(item -> {
            //将角色id 和菜单id放入 roleMenus
            roleMenus.add(new RoleMenu(sysRole.getRoleId(), item));
            //检查刚放入的是否是一个父菜单
            for (MenuVO sysMenu : sysMenus) {
                if (sysMenu.getMenuId().equals(item)) {
                    //如果是一个父菜单 就将 他的子菜单也一起放入
                    sysMenu.getChildren().forEach(c -> {
                        roleMenus.add(new RoleMenu(sysRole.getRoleId(), c.getMenuId()));
                    });
                    break;
                }
            }

        });
        if (!this.roleMenuService.saveBatch(roleMenus)) {
            return R.error();
        }
        return R.ok();
    }


    /**
     * 获取角色列表
     *
     * @param token header token
     * @return R
     */
    @GetMapping("/all")
    public R roleList(@RequestHeader(value = "access-token") String token) {

        String s = JWTUtil.analysisToken(token);
        Map map = JSON.parseObject(s, Map.class);
        Admin admin = this.adminService.getById(map.get("adminId").toString()); //1平台 0店铺
        //获取全部角色
        List<SysRole> sysRoleList = this.sysRoleService.list();
        //获取全部资源
        List<SysApi> sysApiList = this.sysApiService.list();
        //获取全部菜单
        List<SysMenu> sysMenuList = this.sysMenuService.list();
        //获取全部menu role中间表
        List<RoleMenu> roleMenuList = this.roleMenuService.list();
        //获取全部api role 中间表
        List<RoleApi> roleApiList = this.roleApiService.list();
        ArrayList<RoleVO> roleVOS = new ArrayList<>();

        //平台管理员
        if (admin.getAdminType() == 1) {
            sysRoleList.forEach(itemR -> {
                if (itemR.isRoleType()) {
                    RoleVO roleVO = new RoleVO();
                    roleVO.setRoleDes(itemR.getRoleDes());
                    roleVO.setRoleName(itemR.getRoleName());
                    roleVO.setRoleId(itemR.getRoleId());
                    //找出这个角色的资源id
                    ArrayList<String> apis = new ArrayList<>();
                    roleApiList.forEach(itemRA -> {
                        if (itemRA.getRoleId().equals(itemR.getRoleId())) apis.add(itemRA.getApiId());
                    });
                    //找出 资源id的name
                    ArrayList<RoleApiVO> sysApis = new ArrayList<>();
                    //如果包含"0" 则拥有所有资源
                    if (apis.contains("0")) {
                        sysApiList.forEach(itemA -> {
                            RoleApiVO roleApiVO = new RoleApiVO();
                            roleApiVO.setApiId(itemA.getApiId());
                            roleApiVO.setApiName(itemA.getApiName());
                            sysApis.add(roleApiVO);
                        });
                    } else {
                        sysApiList.forEach(itemA -> {
                            if (apis.contains(itemA.getApiId())) {
                                RoleApiVO roleApiVO = new RoleApiVO();
                                roleApiVO.setApiId(itemA.getApiId());
                                roleApiVO.setApiName(itemA.getApiName());
                                sysApis.add(roleApiVO);
                            }
                        });
                    }


                    roleVO.setApis(sysApis);

                    //找出这个角色的菜单id
                    ArrayList<String> menus = new ArrayList<>();
                    roleMenuList.forEach(itemRM -> {
                        if (itemRM.getRoleId().equals(itemR.getRoleId())) menus.add(itemRM.getMenuId());
                    });
                    //找出 菜单id的name
                    ArrayList<RoleMenuVO> roleMenus = new ArrayList<>();
                    if (menus.contains("-1")) {
                        sysMenuList.forEach(itemM -> {
                            //平台管理员
                            if (null != itemM.getMenuPar()) {
                                if (null == itemM.getMenuType() || itemM.getMenuType()) {
                                    RoleMenuVO roleMenuVO = new RoleMenuVO();
                                    roleMenuVO.setMenuId(itemM.getMenuId());
                                    roleMenuVO.setMenuName(itemM.getMenuName());
                                    roleMenus.add(roleMenuVO);
                                }
                            }


                        });
                    } else {
                        sysMenuList.forEach(itemM -> {
                            if ((null != itemM.getMenuPar()) && menus.contains(itemM.getMenuId())) {
                                RoleMenuVO roleMenuVO = new RoleMenuVO();
                                roleMenuVO.setMenuId(itemM.getMenuId());
                                roleMenuVO.setMenuName(itemM.getMenuName());
                                roleMenus.add(roleMenuVO);
                            }
                        });
                    }

                    roleVO.setMenus(roleMenus);


                    roleVOS.add(roleVO);
                }


            });

        } else {
            sysRoleList.forEach(itemR -> {
                if (!itemR.isRoleType()) {
                    RoleVO roleVO = new RoleVO();
                    roleVO.setRoleDes(itemR.getRoleDes());
                    roleVO.setRoleName(itemR.getRoleName());
                    roleVO.setRoleId(itemR.getRoleId());
                    //找出这个角色的资源id
                    ArrayList<String> apis = new ArrayList<>();
                    roleApiList.forEach(itemRA -> {
                        if (itemRA.getRoleId().equals(itemR.getRoleId())) apis.add(itemRA.getApiId());
                    });
                    //找出 资源id的name
                    ArrayList<RoleApiVO> sysApis = new ArrayList<>();
                    //如果包含"0" 则拥有所有资源
                    if (apis.contains("0")) {
                        sysApiList.forEach(itemA -> {
                            RoleApiVO roleApiVO = new RoleApiVO();
                            roleApiVO.setApiId(itemA.getApiId());
                            roleApiVO.setApiName(itemA.getApiName());
                            sysApis.add(roleApiVO);
                        });
                    } else {
                        sysApiList.forEach(itemA -> {
                            if (apis.contains(itemA.getApiId())) {
                                RoleApiVO roleApiVO = new RoleApiVO();
                                roleApiVO.setApiId(itemA.getApiId());
                                roleApiVO.setApiName(itemA.getApiName());
                                sysApis.add(roleApiVO);
                            }
                        });
                    }


                    roleVO.setApis(sysApis);

                    //找出这个角色的菜单id
                    ArrayList<String> menus = new ArrayList<>();
                    roleMenuList.forEach(itemRM -> {
                        if (itemRM.getRoleId().equals(itemR.getRoleId())) menus.add(itemRM.getMenuId());
                    });
                    //找出 菜单id的name
                    ArrayList<RoleMenuVO> roleMenus = new ArrayList<>();
                    if (menus.contains("-1")) {
                        sysMenuList.forEach(itemM -> {
                            //店铺管理员
                            if (null != itemM.getMenuPar()) {
                                if (null == itemM.getMenuType() || !itemM.getMenuType()) {
                                    RoleMenuVO roleMenuVO = new RoleMenuVO();
                                    roleMenuVO.setMenuId(itemM.getMenuId());
                                    roleMenuVO.setMenuName(itemM.getMenuName());
                                    roleMenus.add(roleMenuVO);
                                }
                            }


                        });
                    } else {
                        sysMenuList.forEach(itemM -> {
                            if ((null != itemM.getMenuPar()) && menus.contains(itemM.getMenuId())) {
                                RoleMenuVO roleMenuVO = new RoleMenuVO();
                                roleMenuVO.setMenuId(itemM.getMenuId());
                                roleMenuVO.setMenuName(itemM.getMenuName());
                                roleMenus.add(roleMenuVO);
                            }
                        });
                    }

                    roleVO.setMenus(roleMenus);


                    roleVOS.add(roleVO);
                }


            });

        }


        return R.ok(roleVOS);
    }


    @GetMapping("/del")
    public R roleDel(String roleId) {
        if (this.sysRoleService.removeById(roleId)) {
            return R.ok();
        } else {
            return R.error();
        }
    }

    @PostMapping("/edit")
    public R roleEdit(@RequestBody SysRole sysRole) {
        SysRole role = this.sysRoleService.getById(sysRole.getRoleId());
        if (sysRole.getRoleName().substring(0,5).equals("ROLE_")){
            sysRole.setRoleName(sysRole.getRoleName());
        }else {

            sysRole.setRoleName("ROLE_"+sysRole.getRoleName());
        }
        role.setRoleName(sysRole.getRoleName());
        role.setRoleDes(sysRole.getRoleDes());
        if (this.sysRoleService.saveOrUpdate(role)) {
            return R.ok();
        } else {
            return R.error();
        }

    }

    @PostMapping("/roleApiEdit")
    public R roleApiEdit(@RequestBody RoleApiEditVO roleApiEditVO) {


        QueryWrapper<RoleApi> roleApiQueryWrapper = new QueryWrapper<>();
        roleApiQueryWrapper.eq("role_id",roleApiEditVO.getRoleId());
        this.roleApiService.remove(roleApiQueryWrapper);

        ArrayList<RoleApi> roleApis = new ArrayList<>();
        roleApiEditVO.getApiIds().forEach(item->{
            roleApis.add(new RoleApi(roleApiEditVO.getRoleId(),item));
        });
        if (this.roleApiService.saveBatch(roleApis)) {
            return R.ok();
        }
        return R.error();
    }




    @PostMapping("/roleMenuEdit")
    public R roleMenuEdit(@RequestHeader(value = "access-token") String token,@RequestBody RoleMenuEditVO roleMenuEditVO) {

        String s = JWTUtil.analysisToken(token);
        Map map = JSON.parseObject(s, Map.class);
        Admin admin = this.adminService.getById(map.get("adminId").toString());
        List<SysMenu> list = this.sysMenuService.list();

        //获取全部菜单
        ArrayList<MenuVO> sysMenus = new ArrayList<>();
        if (admin.getAdminType() == 1 && null == admin.getStoreId()) {
            //平台管理员
            list.forEach(item -> {
                //平台管理员 一级菜单
                if ((null == item.getMenuType() || item.getMenuType()) && null == item.getMenuPar()) {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setChildren(new ArrayList<SysMenu>());
                    menuVO.setMenuDes(item.getMenuDes());
                    menuVO.setMenuIcon(item.getMenuIcon());
                    menuVO.setMenuId(item.getMenuId());
                    menuVO.setMenuType(item.getMenuType());
                    menuVO.setMenuName(item.getMenuName());
                    menuVO.setMenuRouter(item.getMenuRouter());

                    list.forEach(item1 -> {
                        if ((null == item1.getMenuType() || item1.getMenuType()) && menuVO.getMenuId().equals(item1.getMenuPar())) {
                            menuVO.getChildren().add(item1);
                        }

                    });
                    sysMenus.add(menuVO);
                }


            });

        } else {
            //店铺管理员
            list.forEach(item -> {
                //平台管理员 一级菜单
                if ((null == item.getMenuType() || !item.getMenuType()) && null == item.getMenuPar()) {
                    MenuVO menuVO = new MenuVO();
                    menuVO.setChildren(new ArrayList<SysMenu>());
                    menuVO.setMenuDes(item.getMenuDes());
                    menuVO.setMenuIcon(item.getMenuIcon());
                    menuVO.setMenuId(item.getMenuId());
                    menuVO.setMenuType(item.getMenuType());
                    menuVO.setMenuName(item.getMenuName());
                    menuVO.setMenuRouter(item.getMenuRouter());
                    list.forEach(item1 -> {
                        if ((null == item1.getMenuType() || !item1.getMenuType()) && menuVO.getMenuId().equals(item1.getMenuPar())) {
                            menuVO.getChildren().add(item1);
                        }

                    });
                    sysMenus.add(menuVO);
                }


            });
        }
        HashSet<RoleMenu> roleMenus = new HashSet<>();
        roleMenuEditVO.getMenuIds().forEach(item -> {
            //将角色id 和菜单id放入 roleMenus


            for (SysMenu sysMenu : list) {
                if (sysMenu.getMenuId().equals(item)){
                    if (null!=sysMenu.getMenuPar()){
                        //是子菜单 将子菜单加入 并找到父菜单也加入
                        roleMenus.add(new RoleMenu(roleMenuEditVO.getRoleId(), item));
                        roleMenus.add(new RoleMenu(roleMenuEditVO.getRoleId(),sysMenu.getMenuPar()));
                        break;
                    }else {
                        //是父菜单
                        for (MenuVO menu : sysMenus) {
                            if (menu.getMenuId().equals(item)){
                                roleMenus.add(new RoleMenu(roleMenuEditVO.getRoleId(), item));
                                menu.getChildren().forEach(i->{
                                    roleMenus.add(new RoleMenu(roleMenuEditVO.getRoleId(), i.getMenuId()));
                                });

                                break;
                            }
                        }
                        break;
                    }
                }
            }



            //是父菜单 直接加入 并找到所有子菜单全加入



        });


        //现将此角色的所有信息删除
        QueryWrapper<RoleMenu> roleMenuQueryWrapper = new QueryWrapper<>();
        roleMenuQueryWrapper.eq("role_id",roleMenuEditVO.getRoleId());
        this.roleMenuService.remove(roleMenuQueryWrapper);
        //再 存入新的信息
        if (this.roleMenuService.saveBatch(roleMenus)) {
            return R.ok();
        } else {
            return R.error();
        }


    }


}
